package utils

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/base64"
	"io"
)

// Encrypt 使用AES-256-CBC模式加密
func Encrypt(plaintext string, key []byte) (string, error) {
	// 确保密钥长度为32字节
	k := make([]byte, 32)
	copy(k, key)

	// 创建cipher
	block, err := aes.NewCipher(k)
	if err != nil {
		return "", err
	}

	// 创建明文块
	content := []byte(plaintext)
	blockSize := block.BlockSize()
	content = pkcs7Pad(content, blockSize)

	// 创建随机IV
	ciphertext := make([]byte, aes.BlockSize+len(content))
	iv := ciphertext[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return "", err
	}

	// 加密
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext[aes.BlockSize:], content)

	// 返回base64编码的结果
	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

// Decrypt 使用AES-256-CBC模式解密
func DecryptByte(encrypted string, key []byte) ([]byte, error) {
	// 确保密钥长度为32字节
	k := make([]byte, 32)
	copy(k, key)

	// 解码base64
	ciphertext, err := base64.StdEncoding.DecodeString(encrypted)
	if err != nil {
		return nil, err
	}

	// 创建cipher
	block, err := aes.NewCipher(k)
	if err != nil {
		return nil, err
	}

	// 检查长度
	if len(ciphertext) < aes.BlockSize {
		return nil, err
	}

	// 提取IV
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	// 解密
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(ciphertext, ciphertext)

	// 去除填充
	content := pkcs7Unpad(ciphertext)
	return content, nil
}
func Decrypt(encrypted string, key []byte) (string, error) {
	b, e := DecryptByte(encrypted, key)
	if e != nil {
		return "", e
	}
	return string(b), e
}

// pkcs7Pad 添加PKCS7填充
func pkcs7Pad(data []byte, blockSize int) []byte {
	padding := blockSize - len(data)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padtext...)
}

// pkcs7Unpad 移除PKCS7填充
func pkcs7Unpad(data []byte) []byte {
	length := len(data)
	if length == 0 {
		return nil
	}
	padding := int(data[length-1])
	return data[:(length - padding)]
}
